package com.ehome.poct.core.service.report;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.MD5;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ehome.poct.core.api.virtual.WxService;
import com.ehome.poct.core.repository.WxProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * 微信认证CMD
 */
@Slf4j
@Component
public class WxServiceImpl implements WxService {
    public static final String WEXIN_TOKEN_KEY = "wexin_access_token";
    @Autowired private RedisTemplate redisTemplate;
    @Autowired private WxProperties wxProperties;
    @Value("${notify.detail.env}") private String enyType;

    /**
     * 获取微信授权
     *
     * @return
     */
    public String getAccessToken(){
        var accessToken = (String) redisTemplate.opsForValue().get(WEXIN_TOKEN_KEY);
        if(accessToken == null){
            var url = String.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
                    wxProperties.getAppId(), wxProperties.getSecret());
            var result = JSONUtil.parseObj(HttpUtil.get(url));
            var tokenObj = result.get("access_token");
            if (ObjectUtil.isNull(tokenObj)) {
                log.error("微信Token获取失败, 微信返回结果:{}", tokenObj);
                return "";
            }
            accessToken = tokenObj.toString();
            redisTemplate.opsForValue().set(WEXIN_TOKEN_KEY, accessToken, 60, TimeUnit.MINUTES);
//            refreshOldToken(accessToken);
        }
        return accessToken;
    }

    /**
     * 根据报告生成推送二维码
     *
     * @param reportId
     * @param type
     * @return
     */
    @Override
    public String generateNotifyUrl(Long reportId, Integer type) {
        var accessToken = getAccessToken();
        String url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token="+accessToken;
        JSONObject body = new JSONObject();
        body.set("expire_seconds",30 * 24 * 3600);
        body.set("action_name", "QR_STR_SCENE");
        JSONObject sid = new JSONObject();
        sid.set("scene_str",type + enyType + reportId);
        JSONObject scene = new JSONObject();
        scene.set("scene",sid);
        body.set("action_info",scene);

        JSONObject result = JSONUtil.parseObj(HttpUtil.post(url, body.toString()));
        var qrUrl = result.get("url");
        if (qrUrl == null) {
            // 获取失败，token过期，删除缓存中的token
            if (result.get("errcode") != null) {
                redisTemplate.delete(WEXIN_TOKEN_KEY);
            }
            log.error("推送二维码获取失败：微信返回结果：{}" + result);
            //如果没有 返回空字符串
            return "nodata";
        }
        return qrUrl.toString();
//        return getWxUrlWithExpire(30 * 24 * 3600, reportId, String.valueOf(type), enyType);
    }

    /**
     * 获取微信openid
     *
     * @param code
     * @return
     */
    public String getWxOpenId(String code) {
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + wxProperties.getAppId()
                + "&secret="+ wxProperties.getSecret() + "&code=" + code + "&grant_type=authorization_code";
        final var obj = JSONUtil.parseObj(HttpUtil.get(url));
        String openId = obj.getStr("openid");
        // 授权失败
        if (StrUtil.isEmpty(openId)) {
            log.error("微信授权失败，微信返回结果：{}", obj);
        }
        return openId;
    }

    /**
     * 刷新老系统的token
     *
     * @param token
     */
    private void refreshOldToken(String token) {
        var url = wxProperties.getRefreshUrl() + "?token=" + token + "&md5=" + MD5.create().digestHex(token + "000390c152af4c489d158093b74ec4ac");
        try {
            var result = HttpUtil.get(url, 2000);
            log.info("更新.NET服务Token结果", result);
        } catch (Exception e) {
            log.error("更新.NET服务微信Token异常，原因：{}", e);
        }
    }
}
